/**
 *  Copyright 2011 Dm. Pavlov
 *  Licensed under the MIT License
 */
 
package org.motiv.core;

import org.motiv.config.Configuration;
import org.motiv.config.CacheConfiguration;
import org.motiv.config.ConfigurationFactory;

import org.apache.log4j.Logger;
import java.util.concurrent.ConcurrentHashMap;

/**
 * A container for {@link Cache}s that maintain all aspects of their lifecycle.
 * @author Pavlov Dm
 */
public class CacheManager {
	/** Logger instance */
	public static final Logger LOG=Logger.getLogger(CacheManager.class);
    /**
     * The Singleton Instance.
     */
    private static volatile CacheManager singleton;
	/**
     * Caches map.
     */
    private final ConcurrentHashMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>();
   /**
	* Class constructor.
	*/
	protected CacheManager() {
		init();
	}
	/**
	* Get CacheManager instance
	* @return CacheManager instance
	*/
	public static CacheManager getInstance() {
		if (singleton != null) {
            return singleton;
        }
        synchronized (CacheManager.class) {
            if (singleton == null) {
				if(LOG.isDebugEnabled()){
					LOG.debug("Creating new CacheManager");
				}
                singleton = new CacheManager();
            }
            return singleton;
        }
	}
	/**
     * Initialises the CacheManager method
     */
    protected void init() {
		//Create configuration
        Configuration configuration = ConfigurationFactory.parseConfiguration();
		ConcurrentHashMap<String, CacheConfiguration> cacheConfigs = configuration.getCacheConfigurations();
		for (CacheConfiguration config : cacheConfigs.values()) {
			Cache cache = CacheFactory.create(config);
			if( cache != null ){
				if(!caches.containsKey(cache.getName())){
					caches.put(cache.getName(),cache);
				}
			}
		}
    }
	/**
     * Returns a concrete implementation of Cache, if it is available in the CacheManager.
     * @return a Cache, if an object of that type exists by that name, else null
     */
    public Cache getCache(String name){
        return (Cache)caches.get(name);
    }
}
